package com.example.web.aspect;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;

/**
 * Web层请求日志切面
 * 统一处理Web层控制器的请求日志记录和请求上下文初始化
 * 
 * @author AI Assistant
 * @since 1.0.0
 */
@Slf4j
@Aspect
@Component
public class WebRequestLogAspect {
    
    /**
     * 定义切点：拦截web.controller包下的所有Controller方法
     */
    @Pointcut("execution(* com.example.web.controller..*.*(..))")
    public void webControllerPointcut() {
    }
    
    /**
     * 环绕通知：记录请求日志和响应日志
     * 
     * @param joinPoint 连接点
     * @return 方法执行结果
     * @throws Throwable 异常
     */
    @Around("webControllerPointcut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        long startTime = System.currentTimeMillis();
        
        // 获取请求信息
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes != null ? attributes.getRequest() : null;
        
        // 获取方法信息
        String className = joinPoint.getTarget().getClass().getSimpleName();
        String methodName = joinPoint.getSignature().getName();
        Object[] args = joinPoint.getArgs();
        
        // 记录请求日志
        if (request != null) {
            String requestId = request.getParameter("requestId");
            String version = request.getParameter("version");
            String uri = request.getRequestURI();
            String method = request.getMethod();
            
            log.info("Web层请求开始 - URI: {}, Method: {}, Class: {}, Method: {}, RequestId: {}, Version: {}, Args: {}", 
                    uri, method, className, methodName, requestId, version, Arrays.toString(args));
        } else {
            log.info("Web层请求开始 - Class: {}, Method: {}, Args: {}", 
                    className, methodName, Arrays.toString(args));
        }
        
        Object result = null;
        try {
            // 执行目标方法
            result = joinPoint.proceed();
            
            // 计算执行时间
            long executionTime = System.currentTimeMillis() - startTime;
            
            // 记录响应日志
            log.info("Web层请求完成 - Class: {}, Method: {}, ExecutionTime: {}ms, Success: true", 
                    className, methodName, executionTime);
            
            return result;
            
        } catch (Throwable e) {
            // 计算执行时间
            long executionTime = System.currentTimeMillis() - startTime;
            
            // 记录异常日志
            log.error("Web层请求异常 - Class: {}, Method: {}, ExecutionTime: {}ms, Error: {}", 
                    className, methodName, executionTime, e.getMessage(), e);
            
            throw e;
        }
    }
}

